#include "kernel/ilog.h"
#include "input/imousedevice.h"
#include "mousedeviceSDL.h"
#include "kernel/debug.h"
#include "mathlib/vec2.h"
#include "inputsystemSDL.h"

namespace rengine3d {

	CMouseDeviceSDL::CMouseDeviceSDL(const string_t name, IRenderDriver* renderDriver, CInputSystemSDL* inputSys) {
		m_inputSys		= inputSys;
		m_name			= name;
		m_sensitivity	= 1.0f;
		m_buttons.resize(mouseButton_Count);
		m_buttons.assign(m_buttons.size(), false);
		m_renderDriver = renderDriver;
	}

	CMouseDeviceSDL::~CMouseDeviceSDL() {
		this->Shutdown();
	}

	bool CMouseDeviceSDL::Init(void) {
		//SDL_WM_GrabInput(SDL_GRAB_ON);			// Take focus
		SDL_ShowCursor(SDL_DISABLE);			// Hide mouse cursor
		SDL_GetRelativeMouseState (NULL, NULL);

		return true;
	}

	void CMouseDeviceSDL::Shutdown(void) {
	}

	void CMouseDeviceSDL::Reset(void) {
		m_relPosition.Set(0, 0);

		int x, y;

		SDL_PumpEvents();
		SDL_GetRelativeMouseState(&x, &y);
	}

	void CMouseDeviceSDL::Update(void) {
		int x, y; 
		CVec2 screenSize	= m_renderDriver->GetScreenSize();
		CVec2 virtualSize	= m_renderDriver->GetVirtualSize();

		//m_buttons.assign(m_buttons.size(), false);

		std::list<SDL_Event>::iterator it = m_inputSys->m_events.begin();
		for(; it != m_inputSys->m_events.end(); ++it) {
			SDL_Event *pEvent = &(*it);

			if(	pEvent->type != SDL_MOUSEMOTION && 
				pEvent->type != SDL_MOUSEBUTTONDOWN &&
				pEvent->type != SDL_MOUSEBUTTONUP) {
					continue;
			}

			if(pEvent->type == SDL_MOUSEMOTION) {
				CVec2 absPos = CVec2((float)pEvent->motion.x, (float)pEvent->motion.y);
				m_absPosition = (absPos / screenSize)* virtualSize;
				Uint8 buttonState = pEvent->motion.state;

			}
			else {
				bool bButtonIsDown = pEvent->type==SDL_MOUSEBUTTONDOWN;

				switch(pEvent->button.button)
				{
				case SDL_BUTTON_LEFT:		m_buttons[mouseButton_Left]		= bButtonIsDown;break;
				case SDL_BUTTON_MIDDLE:		m_buttons[mouseButton_Middle]	= bButtonIsDown;break;
				case SDL_BUTTON_RIGHT:		m_buttons[mouseButton_Right]	= bButtonIsDown;break;
				case SDL_BUTTON_WHEELUP: 
					m_buttons[mouseButton_WheelUp] = bButtonIsDown;
					break;
				case SDL_BUTTON_WHEELDOWN: 
					m_buttons[mouseButton_WheelDown] = bButtonIsDown;
					break;
				}
			}
		}

		SDL_GetRelativeMouseState(&x, &y);

		m_relPosition = CVec2((float)x, (float)y);
		m_relPosition = (m_relPosition/screenSize) * virtualSize;

	}

	void CMouseDeviceSDL::SetCursorPos(int x, int y)  {
		//SDL_Window* wnd= SDL_GetMouseFocus(void);
		//SDL_WarpMouseInWindow(SDL_GetMouseFocus(), x, y);

	}

	void CMouseDeviceSDL::SetSensitivity(real value) {
		m_sensitivity = value;
	}

	real CMouseDeviceSDL::GetSensitivity(void) const {
		return m_sensitivity;
	}

	CVec2 CMouseDeviceSDL::GetAbsPosition(void) {
		return m_absPosition;
	}

	CVec2 CMouseDeviceSDL::GetRelPosition(void) {
		int mx, my;
		SDL_GetRelativeMouseState (&mx, &my);
		//return CVec2(mx, my);
		return m_relPosition;
	}

	bool CMouseDeviceSDL::ButtonIsDown(mouseButton_t button) {
		return m_buttons[button];
	}

}
